<?php
/**
 * Created by PhpStorm.
 * User: ouryun
 * Date: 2021/5/12
 * Time: 17:13
 */

namespace app\api\controller;


use app\api\model\DistributorModel;
use think\admin\Controller;
use think\facade\Cache;
use think\facade\Db;

/**
 * 好望云接口
 * Class Hwy
 * @package app\api\controller
 */
class Hwy extends Controller
{
    protected $ak = '7c7eb6ec0c8204ef88412144f0afc71b';
    protected $sk = 'e2d5dce1e3f03b262b23af9d594451a927494d3d3dcfecc09666c3724bd5dd28';
    protected $user_id = '38376590220210408143507';
    protected $uri = 'https://api-ivm.myhuaweicloud.com/v1/';

    /**
     * 获取token
     * @return \think\response\Json
     */
    public function getAccessTokenAction()
    {
        $token = $this->_getToken();
        if (!$token) {
            return returnJson(HTTP_CODE_ERROR, '获取失败', '');
        }
        return returnJson(HTTP_CODE_SUCCESS, '', ['access_token' => $token]);
    }

    /**
     * 获取Access-Token
     * @return bool|mixed
     */
    public function _getToken()
    {
        $token = Cache::get('access_token');
        if (empty($token)) {
            $url = $this->uri . $this->user_id . '/enterprises/access-token';
            $data = [
                'ak' => $this->ak,
                'sk' => $this->sk
            ];
            $params = json_encode($data);
            $header = array("Content-type:application/json;charset='utf-8'", "Accept:application/json");
            $result = curl_post_request($url, $params, $header);
            if (!isset($result['access_token'])) {
                return ['code' => 0, 'msg' => '获取token失败'];
            }
            $token = $result['access_token'];
            Cache::set('access_token', $token, 86400 * 6);  //设置6天
        }
        return $token;
    }

    /**
     * 获取设备列表
     */
    protected function _getDevices()
    {
        $token = $this->_getToken();
        if (isset($token['code']) && $token['code'] == 0) {
            return ['code' => 0, 'msg' => $token['msg']];
        }
        $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
        $url = $this->uri . $this->user_id . '/devices';
        $result = curl_get_request($url, $header);
        if (isset($result['error_code']) && $result['error_msg'] == 'Authentication failure.') {
            Cache::set('access_token', '');
            $token = $this->_getToken();
            if (isset($token['code']) && $token['code'] == 0) {
                return ['code' => 0, 'msg' => $token['msg']];
            }
            $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
            $url = $this->uri . $this->user_id . '/devices';
            $result = curl_get_request($url, $header);
        }
        if (!isset($result['devices'])) {
            return ['code' => 0, 'msg' => '获取设备列表失败'];
        }
        $deviceList = $result['devices'];
        if (empty($deviceList)) {
            return ['code' => 0, 'msg' => '设备列表为空'];
        }
        $devices = [];
        foreach ($deviceList as $key => $value) {
            if ($value['device_state'] == 'ONLINE') {
                $devices[] = $value['device_id'];
            }
        }
        return $devices;
    }

    /**
     * 获取通道列表
     */
    public function _getChannels()
    {
        $token = $this->_getToken();
        if (isset($token['code']) && $token['code'] == 0) {
            return ['code' => 0, 'msg' => $token['msg']];
        }
        $devices = $this->_getDevices();
        if (isset($devices['code']) && $devices['code'] == 0) {
            return ['code' => 0, 'msg' => $devices['msg']];
        }
        $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
        $url = $this->uri . $this->user_id . '/channels?limit=1000';
        $result = curl_get_request($url, $header);
        if (!isset($result['channels'])) {
            return ['code' => 0, 'msg' => '获取通道列表失败'];
        }
        $channelList = $result['channels'];
        $channelArr = [];
        foreach ($channelList as $key => $value) {
            if (in_array($value['device_id'], $devices)) {
                $channelArr[] = $value;
            }
        }
        $channels = [];
        $i = 0;
        foreach ($channelArr as $key => $value) {
            if ($value['channel_state'] == 'ONLINE') {
                $channels[$i]['device_id'] = $value['device_id'];
                $channels[$i]['channel_id'] = $value['channel_id'];
                $channels[$i]['stream_type'] = 'SECONDARY_STREAM_1';//主码流/次码流(PRIMARY_STREAM/SECONDARY_STREAM_1)
                $i++;
            }
        }
        return $channels;
    }

    /**
     * 获取摄像头视频流
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getWebUrlListAction()
    {
        header('Access-Control-Allow-Origin:*');
        header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
        header('Access-Control-Allow-Credentials:false');
        $token = $this->_getToken();
        if (isset($token['code']) && $token['code'] == 0) {
            return returnJson(HTTP_CODE_ERROR, $token['msg'], '');
        }
        $channels = $this->_getChannels();
        if (isset($channels['code']) && $channels['code'] == 0) {
            return returnJson(HTTP_CODE_ERROR, $channels['msg'], '');
        }
        //获取设备id
        $deviceIdArr = array_unique(array_column($channels, 'device_id'));
        $shopIds = (new DistributorModel())->getShopId($deviceIdArr);
        $distrList = Db::name('lg_distributor')->whereIn('id', array_keys($shopIds))->field('id,name')->select()->toArray();
        foreach ($distrList as $key => $value) {
            $distrList[$key]['device_id'] = $shopIds[$value['id']] ?? '';
        }
        $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
        $url = $this->uri . $this->user_id . '/devices/channels/cloud-live/web-url';
        $data = json_encode(['channels' => $channels]);
        $result = curl_post_request($url, $data, $header);
        if (!isset($result['channels']) || empty($result['channels'])) {
            return returnJson(HTTP_CODE_ERROR, '获取失败，请检查设备', '');
        }
        foreach ($result['channels'] as $key => $value) {
            $result['channels'][$key]['shop_name'] = '';
            foreach ($distrList as $k => $v) {
                if ($value['device_id'] == $v['device_id']) {
                    $result['channels'][$key]['shop_name'] = $v['name'];
                }
            }
        }
        $num = Cache::get('hwy_num');
        if (empty($num)) {
            Cache::set('hwy_num', 1);
        } else {
            Cache::set('hwy_num', $num + 1);
        }
        $num = Cache::get('hwy_num');
        $chunkArr = array_chunk($result['channels'], 9);
        if ($num > count($chunkArr)) {
            Cache::set('hwy_num', '');
            $num = 1;
        }
        $list = [];
        $list['failNum'] = $result['failNum'] ?? 0;
        $list['channels'] = $chunkArr[$num - 1];
        return returnJson(HTTP_CODE_SUCCESS, '', $result);
    }

    /**
     * 获取回放
     * @param $device_id
     * @param $channel_id
     * @param string $startTime
     * @param string $endTime
     * @return mixed
     */
    public function getPlaybackUrl($device_id, $channel_id, $startTime = '', $endTime = '')
    {
        $token = $this->_getToken();
        $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
        if (empty($startTime)) {
            $startTime = date('Y-m-d', time()) . '+00:00:00';
            $endTime = date('Y-m-d', strtotime('+1 day', time())) . '+00:00:00';
        }
        $params = "?&start_time={$startTime}&end_time={$endTime}";
        //获取云录像
        //$url = $this->uri . $this->user_id . "/devices/{$device_id}/channels/{$channel_id}/cloud-records/web-playback-url" . $params;
        //获取设备本地录像
        $url = $this->uri . $this->user_id . "/devices/{$device_id}/channels/{$channel_id}/device-records/web-playback-url" . $params;
        $result = curl_get_request($url, $header);
        if (isset($result['error_code']) && $result['error_msg'] == 'Authentication failure.') {
            Cache::set('access_token', '');
            $token = $this->_getToken();
            $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
            if (empty($startTime)) {
                $startTime = date('Y-m-d', time()) . '+00:00:00';
                $endTime = date('Y-m-d', strtotime('+1 day', time())) . '+00:00:00';
            }
            $params = "?&start_time={$startTime}&end_time={$endTime}";
            //获取云录像
            //$url = $this->uri . $this->user_id . "/devices/{$device_id}/channels/{$channel_id}/cloud-records/web-playback-url" . $params;
            //获取设备本地录像
            $url = $this->uri . $this->user_id . "/devices/{$device_id}/channels/{$channel_id}/device-records/web-playback-url" . $params;
            $result = curl_get_request($url, $header);
        }
        return $result;
    }

    /**
     * 获取回放
     * @return \think\response\Json
     */
    public function getPlaybackUrlAction()
    {
        $data = $this->request->param();
        $valiResult = $this->app->validate->check($data, [
            'time|时间' => 'require',
            'device_id|设备id' => 'require',
            'channel_id|通道id' => 'require'
        ]);
        if ($valiResult !== true) {
            return returnJson(HTTP_CODE_ERROR, $this->app->validate->getError(), '');
        }
        if (strpos($data['time'], ' - ') === false) {
            return returnJson(HTTP_CODE_ERROR, '时间格式不正确', '');
        }
        $timeArr = explode(' - ', $data['time']);
        $startTime = str_replace(' ', '+', $timeArr[0]);
        $endTime = str_replace(' ', '+', $timeArr[1]);
        $result = $this->getPlaybackUrl($data['device_id'], $data['channel_id'], $startTime, $endTime);
        if (isset($result['error_code'])) {
            return returnJson(HTTP_CODE_ERROR, $result['error_msg'], '');
        }
        return returnJson(HTTP_CODE_SUCCESS, '', $result);
    }

    /**
     * @return \think\response\Json
     */
    public function cloudRecordsAction()
    {
        $data = $this->request->param();
        $valiResult = $this->app->validate->check($data, [
            'startTime|开始时间' => 'require',
            'endTime|结束时间' => 'require',
            'device_id|设备id' => 'require',
            'channel_id|通道id' => 'require'
        ]);
        if ($valiResult !== true) {
            return returnJson(HTTP_CODE_ERROR, $this->app->validate->getError(), '');
        }
        $token = $this->_getToken();
        $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
        $url = $this->uri . $this->user_id . "/devices/{$data['device_id']}/channels/{$data['channel_id']}/cloud-records?start_time={$data['startTime']}&end_time={$data['endTime']}&limit=100";
        $result = curl_get_request($url, $header);
        if (isset($result['error_code']) && $result['error_msg'] == 'Authentication failure.') {
            Cache::set('access_token', '');
            $token = $this->_getToken();
            $header = array("Content-type:application/json;", "Accept:application/json", "Access-Token:$token");
            $url = $this->uri . $this->user_id . "/devices/{$data['device_id']}/channels/{$data['channel_id']}/cloud-records?start_time={$data['startTime']}&end_time={$data['endTime']}&limit=100";
            $result = curl_get_request($url, $header);
        }
        $result['info'] = [
            'ak' => $this->ak,
            'sk' => $this->sk,
            'user_id' => $this->user_id,
            'token' => $token,
            'startTime' => $data['startTime'],
            'endTime' => $data['endTime'],
            'device_id' => $data['device_id'],
            'channel_id' => $data['channel_id']
        ];
        return returnJson(HTTP_CODE_SUCCESS, '', $result);
    }
}